package com.ruoyi.wechat.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.MsgType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.wx.WechatUtils;
import com.ruoyi.wechat.domain.MsgRequest;
import com.ruoyi.wechat.service.IWechatAppSenderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;


/**
 * 微信小程序推送告警消息实现类
 */
@Service
public class WechatAppSenderServiceImpl implements IWechatAppSenderService {

    private static final Logger log = LoggerFactory.getLogger(WechatAppSenderServiceImpl.class);

    @Autowired
    private RedisCache redisCache;

    /**
     * 运维小小工公众号报警模板id
     */
    @Value("${wechat.miniprogram.order.templateId}")
    private String templateId;

    /**
     * 运维小小工公众号 appid
     */
    @Value("${wechat.miniprogram.offiaccount.appid}")
    private String offiaccountAppid;

    /**
     * 运维小小工公众号 appid
     */
    @Value("${wechat.miniprogram.appid}")
    private String appid;

    /**
     * 公众号推送工单消息字体颜色
     */
    @Value("${wechat.miniprogram.order.color}")
    private String orderColor;

    /**
     * 功能描述:    第一次执行时先获取下小程序access_token
     *
     * @Author wanghc
     * @Date 2022/08/20 19:39
     * @param
     * @return void
     */
    public void refreshAccessToken() {
        log.info(">>>>>>>>>>>>>>>>>执行定时刷新小程序access_token时间: " + LocalDateTime.now());
        // 获取access_token:通过自定义工具类组合出小程序需要的获取access_token的url
        String requestUrl = WechatUtils.getMiniprogramAccessToken();
        log.info("》》》获取openid接口为：" + requestUrl);
        JSONObject sessionData = HttpUtils.httpsRequest(requestUrl, "GET", null);
        log.info(sessionData.toJSONString());
        if (null != sessionData && StringUtils.isNotEmpty(sessionData.getString(CacheConstants.ACCESS_TOKEN))) {
            redisCache.setCacheObject(CacheConstants.getAccessTokenCacheKey(), sessionData.getString(CacheConstants.ACCESS_TOKEN));
            log.info("》》》获取接口调用凭证：" + redisCache.getCacheObject(CacheConstants.getAccessTokenCacheKey()));
        }
    }

    /**
     * 功能描述: 公众号统一推送工单消息
     *
     * @Author wanghc
     * @Date 2022/08/21 10:37
     * @param msgRequest 消息请求
     * @param type 1-抢单消息，2-已接单通知，3-完成通知，4-接单后被取消通知
     * @return void
     */
    @Override
    public void sendOrderMessage(MsgRequest msgRequest, String type){
        String accessToken = "";
        // 获取access_token
        if (StringUtils.isNotNull(redisCache.getCacheObject(CacheConstants.getAccessTokenCacheKey()))) {
            accessToken = redisCache.getCacheObject(CacheConstants.getAccessTokenCacheKey()).toString();
        }else{
            // 获取access_token
            refreshAccessToken();
            accessToken = redisCache.getCacheObject(CacheConstants.getAccessTokenCacheKey()).toString();
        }
        // 通过自定义工具类组合出小程序推送消息的url
        String requestUrl = WechatUtils.getMiniprogramPushMsgUrl(accessToken);

        // 公众号模板消息相关的信息-组织抢单信息
        JSONObject mpTemplateMsgJson = this.organizeReserveOrderMsgJson(msgRequest, type);
        if(CollUtil.isNotEmpty(msgRequest.getOpenids())){
            for(String openid : msgRequest.getOpenids()) {
                log.error("》》》小程序遍历openid循环推送消息：openid -->" + openid);
                //封装请求体
                JSONObject alarmMsgJson = new JSONObject();
                alarmMsgJson.put("touser", openid);
                alarmMsgJson.put("mp_template_msg", mpTemplateMsgJson);
                JSONObject sessionData = HttpUtils.httpsRequest(requestUrl, "POST", alarmMsgJson.toJSONString());
                log.error("》》》小程序推送消息返回结果：" + sessionData);
            }
        }
    }

    /**
     * 功能描述:   组织抢单信息
     *
     * @Author wanghc
     * @Date 2022/08/21 10:30
     * @param msgRequest
     * @param type 1-抢单消息，2-已接单通知，3-完成通知，4-接单后被取消通知
     * @return com.alibaba.fastjson2.JSONObject
     */
    private JSONObject organizeReserveOrderMsgJson(MsgRequest msgRequest, String type){
        String title = "您好，有新的工单等待抢单，请点击查看：";
        if(StringUtils.isNotEmpty(type) && MsgType.UNRECEIVE.getCode().equals(type)){
            title = "您好，有新的工单等待抢单，请点击查看：";
        } else if(StringUtils.isNotEmpty(type) && MsgType.RECEIVE.getCode().equals(type)){
            title = "您提交的工单已接单，请点击查看：";
        } else if(StringUtils.isNotEmpty(type) && MsgType.FINISHED.getCode().equals(type)){
            title = "您提交的工单已完成，请点击查看：";
        } else if(StringUtils.isNotEmpty(type) && MsgType.CANCEL.getCode().equals(type)){
            title = "您有进行中的工单被取消，请点击查看：";
        } else if(StringUtils.isNotEmpty(type) && MsgType.REVOKE.getCode().equals(type)){
            title = "您有工单被撤单，已重新开放抢单，请点击查看：";
        }
        // 组织公众号模板消息相关的信息
        JSONObject mpTemplateMsgJson = new JSONObject();
        //公众号appid，要求与小程序有绑定且同主体
        mpTemplateMsgJson.put("appid", offiaccountAppid);
        mpTemplateMsgJson.put("template_id", templateId);
        mpTemplateMsgJson.put("url", "");

        // 组织公众号模板消息所要跳转的小程序，小程序的必须与公众号具有绑定关系
        JSONObject miniprogramJson = new JSONObject();
        miniprogramJson.put("appid", WechatUtils.getAppId());
        //path 只能跳转小程序首页， 配置pagepath/usepath false可跳转指定页面
        miniprogramJson.put("pagepath", WechatUtils.getMiniprogramPagePath(msgRequest.getOrderManage().getId()));
//        miniprogramJson.put("path", WechatUtils.getMiniprogramPagePath(msgRequest.getOrderManage().getId()));
        miniprogramJson.put("usepath", false);
        mpTemplateMsgJson.put("miniprogram", miniprogramJson);
        // 组织公众号模板消息的数据
        JSONObject dataJson = new JSONObject();
        JSONObject firstJson = new JSONObject();
        firstJson.put("value", title);
        dataJson.put("first", firstJson);
        JSONObject keywordJson1 = new JSONObject();
        keywordJson1.put("value", msgRequest.getOrderManage().getOrderCode());
        keywordJson1.put("color", "#" + orderColor);
        dataJson.put("keyword1", keywordJson1);
        JSONObject keywordJson2 = new JSONObject();
        keywordJson2.put("value", DateUtil.formatDateTime(msgRequest.getOrderManage().getBookingTime()));
        keywordJson2.put("color", "#" + orderColor);
        dataJson.put("keyword2", keywordJson2);
        JSONObject keywordJson3 = new JSONObject();
        keywordJson3.put("value", msgRequest.getOrderManage().getOrderTypeShow());
        dataJson.put("keyword3", keywordJson3);
        JSONObject keywordJson4 = new JSONObject();
        keywordJson4.put("value", msgRequest.getOrderManage().getOrderStatusShow());
        dataJson.put("keyword4", keywordJson4);
        JSONObject remarkJson = new JSONObject();
        String location = StringUtils.isEmpty(msgRequest.getOrderManage().getLocation()) ? "":msgRequest.getOrderManage().getLocation();
        remarkJson.put("value", StringUtils.format("维修地点：{}", location));
        dataJson.put("remark", remarkJson);
        mpTemplateMsgJson.put("data", dataJson);
        return mpTemplateMsgJson;
    }



}
